<template>
  <view class="upload-container" @click="hideSortButtons">
    <!-- 已上传的文件列表 -->
    <view class="upload-list">
      <view
        v-for="(item, index) in fileList"
        :key="index"
        class="upload-item"
        @longpress="enableDrag ? showSortButtons(index) : null"
      >
        <!-- 图片预览 -->
        <image
          v-if="item.type === 'image'"
          :src="item.url"
          class="upload-preview"
          mode="aspectFill"
          @click="previewImage(item.url)"
        />
        <!-- 视频预览 -->
        <video
          v-else-if="item.type === 'video'"
          :src="item.url"
          class="upload-preview"
          controls
        />

        <!-- 删除按钮 -->
        <view class="delete-btn" @click.stop="deleteFile(index)">
          <uni-icons type="close" size="16" color="#fff"></uni-icons>
        </view>

        <!-- 排序按钮（长按显示） -->
        <view v-if="enableDrag && sortIndex === index" class="sort-buttons">
          <view v-if="index > 0" class="sort-btn" @click.stop="moveLeft(index)">
            <uni-icons type="left" size="20" color="#fff"></uni-icons>
          </view>
          <view
            v-if="index < fileList.length - 1"
            class="sort-btn"
            @click.stop="moveRight(index)"
          >
            <uni-icons type="right" size="20" color="#fff"></uni-icons>
          </view>
        </view>
      </view>

      <!-- 上传按钮 -->
      <view
        v-if="fileList.length < maxCount"
        class="upload-btn"
        @click="chooseFile"
      >
        <uni-icons type="camera-filled" size="40" color="#999"></uni-icons>
        <text class="upload-text">{{ uploadText }}</text>
      </view>
    </view>

    <!-- 提示文本 -->
    <view v-if="tipText" class="tip-text">
      <text>{{ tipText }}</text>
    </view>
  </view>
</template>

<script setup>
import { ref, computed } from "vue";
import { uploadToOss } from "@/utils/oss";

const props = defineProps({
  // 已上传的文件列表
  modelValue: {
    type: Array,
    default: () => [],
  },
  // 上传类型: image, video, all
  uploadType: {
    type: String,
    default: "image",
  },
  // 最大上传数量
  maxCount: {
    type: Number,
    default: 10,
  },
  // 最大文件大小(MB)
  maxSize: {
    type: Number,
    default: 5,
  },
  // 上传按钮文字
  uploadText: {
    type: String,
    default: "选择图片",
  },
  // 提示文本
  tipText: {
    type: String,
    default: "",
  },
  // 是否启用拖动排序
  enableDrag: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(["update:modelValue", "change"]);

// 文件列表
const fileList = computed({
  get: () => props.modelValue,
  set: (val) => {
    emit("update:modelValue", val);
    emit("change", val);
  },
});

// 选择文件
const chooseFile = () => {
  if (fileList.value.length >= props.maxCount) {
    uni.showToast({
      title: `最多上传${props.maxCount}个文件`,
      icon: "none",
    });
    return;
  }

  // 根据类型选择不同的方法
  if (props.uploadType === "image") {
    chooseImage();
  } else if (props.uploadType === "video") {
    chooseVideo();
  } else {
    // 显示选择对话框
    uni.showActionSheet({
      itemList: ["选择图片", "选择视频"],
      success: (res) => {
        if (res.tapIndex === 0) {
          chooseImage();
        } else if (res.tapIndex === 1) {
          chooseVideo();
        }
      },
    });
  }
};

// 选择图片
const chooseImage = () => {
  const remainCount = props.maxCount - fileList.value.length;

  uni.chooseImage({
    count: remainCount,
    sizeType: ["compressed"],
    sourceType: ["album", "camera"],
    success: async (res) => {
      const tempFiles = res.tempFiles;

      // 检查文件大小
      const oversizeFiles = tempFiles.filter(
        (file) => file.size > props.maxSize * 1024 * 1024
      );

      if (oversizeFiles.length > 0) {
        uni.showToast({
          title: `文件大小不能超过${props.maxSize}M`,
          icon: "none",
        });
        return;
      }

      // 显示加载提示
      uni.showLoading({
        title: "上传中...",
        mask: true,
      });

      try {
        // 上传文件到 OSS
        const uploadPromises = tempFiles.map(async (file, index) => {
          const result = await uploadToOss(file.path, {
            prefix: "merchant/images/",
            onProgress: (progress) => {
              // 更新加载提示
              uni.showLoading({
                title: `上传中 ${index + 1}/${tempFiles.length} (${progress}%)`,
                mask: true,
              });
            },
          });

          return {
            url: result.url,
            type: "image",
            size: file.size,
          };
        });

        const uploadedFiles = await Promise.all(uploadPromises);

        // 添加到文件列表
        fileList.value = [...fileList.value, ...uploadedFiles];

        uni.hideLoading();
        uni.showToast({
          title: "上传成功",
          icon: "none",
        });
      } catch (error) {
        console.error("上传失败:", error);
        uni.hideLoading();
        uni.showToast({
          title: error.message || "上传失败，请重试",
          icon: "none",
        });
      }
    },
  });
};

// 选择视频
const chooseVideo = () => {
  uni.chooseVideo({
    sourceType: ["album", "camera"],
    maxDuration: 60,
    camera: "back",
    success: async (res) => {
      // 检查文件大小
      if (res.size > props.maxSize * 1024 * 1024) {
        uni.showToast({
          title: `视频大小不能超过${props.maxSize}M`,
          icon: "none",
        });
        return;
      }

      // 显示加载提示
      uni.showLoading({
        title: "上传中...",
        mask: true,
      });

      try {
        // 上传视频到 OSS
        const result = await uploadToOss(res.tempFilePath, {
          prefix: "merchant/videos/",
          onProgress: (progress) => {
            uni.showLoading({
              title: `上传中 (${progress}%)`,
              mask: true,
            });
          },
        });

        // 添加到文件列表
        fileList.value = [
          ...fileList.value,
          {
            url: result.url,
            type: "video",
            size: res.size,
            duration: res.duration,
          },
        ];

        uni.hideLoading();
        uni.showToast({
          title: "上传成功",
          icon: "none",
        });
      } catch (error) {
        console.error("上传失败:", error);
        uni.hideLoading();
        uni.showToast({
          title: error.message || "上传失败，请重试",
          icon: "none",
        });
      }
    },
  });
};

// 预览图片
const previewImage = (url) => {
  const imageUrls = fileList.value
    .filter((item) => item.type === "image")
    .map((item) => item.url);

  uni.previewImage({
    current: url,
    urls: imageUrls,
  });
};

// 删除文件
const deleteFile = (index) => {
  uni.showModal({
    title: "提示",
    content: "确认删除该文件吗？",
    success: (res) => {
      if (res.confirm) {
        const newList = [...fileList.value];
        newList.splice(index, 1);
        fileList.value = newList;
      }
    },
  });
};

// 拖动排序相关
const sortIndex = ref(-1);

// 显示排序按钮
const showSortButtons = (index) => {
  if (!props.enableDrag) return;
  sortIndex.value = index;
  uni.vibrateShort();
};

// 隐藏排序按钮
const hideSortButtons = () => {
  sortIndex.value = -1;
};

// 向左移动
const moveLeft = (index) => {
  if (index <= 0) return;

  const newList = [...fileList.value];
  [newList[index - 1], newList[index]] = [newList[index], newList[index - 1]];
  fileList.value = newList;
  sortIndex.value = index - 1;
};

// 向右移动
const moveRight = (index) => {
  if (index >= fileList.value.length - 1) return;

  const newList = [...fileList.value];
  [newList[index], newList[index + 1]] = [newList[index + 1], newList[index]];
  fileList.value = newList;
  sortIndex.value = index + 1;
};
</script>

<style lang="scss" scoped>
.upload-container {
  width: 100%;
}

.upload-list {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
}

.upload-item {
  position: relative;
  width: 160rpx;
  height: 160rpx;
  border-radius: 12rpx;
  overflow: visible;
  transition: transform 0.2s;
}

.sort-buttons {
  position: absolute;
  bottom: -50rpx;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 16rpx;
  z-index: 101;
}

.sort-btn {
  width: 60rpx;
  height: 60rpx;
  background-color: rgba(0, 0, 0, 0.7);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3);

  &:active {
    opacity: 0.8;
  }
}

.upload-preview {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 12rpx;
  overflow: hidden;
}

.delete-btn {
  position: absolute;
  top: 8rpx;
  right: 8rpx;
  width: 40rpx;
  height: 40rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;

  &:active {
    opacity: 0.8;
  }
}

.upload-btn {
  width: 160rpx;
  height: 160rpx;
  background-color: #f5f5f5;
  border-radius: 12rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  &:active {
    opacity: 0.8;
  }
}

.upload-text {
  font-size: 24rpx;
  color: #999;
}

.tip-text {
  margin-top: 16rpx;
  font-size: 24rpx;
  color: #999;
  line-height: 1.5;
}
</style>
